{/* Copyright 2020 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License. */}

import {Layout} from '@react-spectrum/docs';
export default Layout;

import docs from 'docs:@react-spectrum/slider';
import {HeaderInfo, PropTable, PageDescription} from '@react-spectrum/docs';
import packageData from '@react-spectrum/slider/package.json';

```jsx import
import {Flex} from '@react-spectrum/layout';
import {RangeSlider} from '@react-spectrum/slider';
```

---
category: Forms
after_version: 3.0.0-alpha.0
---

# RangeSlider

<PageDescription>{docs.exports.RangeSlider.description}</PageDescription>

<HeaderInfo
packageData={packageData}
componentNames={['RangeSlider']}
sourceData={[{type: 'Spectrum', url: 'https://spectrum.adobe.com/page/slider/'}]}
since="3.7.0" />

## Example

```tsx example
<RangeSlider label="Range" defaultValue={{start: 12, end: 36}} />
```

## Value

RangeSliders are controlled with the `value` prop and uncontrolled with the `defaultValue` prop.
This value consists of two parts, `start` and `end`. Both parts must fall between
the RangeSlider's minimum and maximum values, which default to 0 and 100 respectively.

```tsx example
function Example() {
  let [value, setValue] = React.useState({start: 25, end: 75});
  return (
    <Flex gap="size-150" wrap>
      <RangeSlider
        label="Range (uncontrolled)"
        defaultValue={{start: 25, end: 75}} />
      <RangeSlider
        label="Range (controlled)"
        value={value}
        onChange={setValue} />
    </Flex>
  );
}
```

Alternatively, a different scale can be used by setting the `minValue` and `maxValue` props.

```tsx example
<RangeSlider
  label="Range"
  minValue={50}
  maxValue={150}
  defaultValue={{start: 75, end: 100}} />
```

The slider value can be formatted by using the `formatOptions` prop.
`formatOptions` is compatible with the option parameter of [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat) and is applied based on the current locale.

```tsx example
<RangeSlider
  label="Price range"
  formatOptions={{style: 'currency', currency: 'JPY'}}
  defaultValue={{start: 75, end: 100}} />
```

### HTML forms

RangeSlider supports the `startName` and `endName` props for integration with HTML forms.

```tsx example
<RangeSlider
  label="Range"
  defaultValue={{start: 12, end: 36}}
  startName="start"
  endName="end" />
```

## Labeling
Value labels are shown above the Slider by default, but they can also be moved to the side or hidden as needed.
The label text should be in sentence case.

```tsx example
<Flex direction="column" maxWidth="size-5000" gap="size-300">
  <RangeSlider label="Jeans price range" formatOptions={{style: 'currency', currency: 'USD'}} defaultValue={{start: 75, end: 100}} />
  <RangeSlider label="Shoes price range" formatOptions={{style: 'currency', currency: 'USD'}} labelPosition="side" defaultValue={{start: 50, end: 100}} />
  <RangeSlider label="Hats price range" formatOptions={{style: 'currency', currency: 'USD'}} showValueLabel={false} defaultValue={{start: 15, end: 30}} />
</Flex>
```

By default, the value label is formatted as a plain number. This can be customized using the following props.

* `showValueLabel`: Allows you to display or hide the value label.
* `formatOptions`: Allows you to customize the format of the value.
* `getValueLabel`: Allows you to provide a custom function to format the value label.

```tsx example
<Flex direction="column" maxWidth="size-3000" gap="size-300">
  <RangeSlider
    label="Level range"
    showValueLabel={false}
    defaultValue={{start: 75, end: 100}} />

  <RangeSlider
    label="Cacao percentage"
    maxValue={1}
    step={0.001}
    formatOptions={{style: 'percent', minimumFractionDigits: 1}}
    defaultValue={{start: .75, end: 1}} />

  <RangeSlider
    label="Search radius"
    maxValue={200}
    getValueLabel={meters => `${meters.start}m to ${meters.end}m away`}
    defaultValue={{start: 15, end: 60}} />
</Flex>
```

### Accessibility

Depending on the visualization being used (i.e. depending on the `showValueLabel` prop), a `label`, `aria-label`, or `aria-labelledby` prop is required.

### Internationalization

To internationalize a Slider, a localized string should be passed to the `label` prop, `aria-label` prop, or value of the associated `aria-labelledby` element.

For languages that are read right-to-left (e.g. Hebrew and Arabic), the layout of the slider is automatically flipped. In addition,
Slider automatically uses the current locale to format the value label.

## Props

<PropTable component={docs.exports.RangeSlider} links={docs.links} />

## Visual options

### Contextual help

A [ContextualHelp](ContextualHelp.html) element may be placed next to the label to provide additional information or help about a RangeSlider.

```tsx example
import {Content, ContextualHelp, Heading} from '@adobe/react-spectrum';

<RangeSlider
  label="Search radius"
  formatOptions={{style: 'unit', unit: 'mile'}}
  defaultValue={{start: 15, end: 60}}
  contextualHelp={
    <ContextualHelp variant="info">
      <Heading>Ranking</Heading>
      <Content>Search results are sorted by distance from city center.</Content>
    </ContextualHelp>
  } />
```

### Disabled
[View guidelines](https://spectrum.adobe.com/page/slider/#Disabled)

```tsx example
<RangeSlider label="Price filter" defaultValue={{start: 25, end: 50}} isDisabled />
```
